/**********************************************************
    COPYRIGHT
       LGX (c) 2011
    CLASS NAME
        platform_main.c
    DEPENDENCY

    HISTORY
		08/19/2011, created by Guangxing Liu
**********************************************************/

/************************INCLUDE**************************/
#include "platform_uart.h"
#include "platform_config.h"
#include "lpc177x_8x_timer.h"
#include "lpc177x_8x_clkpwr.h"
#include "lpc177x_8x_gpio.h"
#include "platform_timer.h"
#include "platform_gpio.h"
#include "platform_cpld.h"
#include "platform_gcode.h"
#ifdef WIN32_PLATFORM
#include <windows.h>
#endif
#include "lpc177x_8x.h"
#include "lpc_types.h"
#include "lpc177x_8x_mci.h"
#include "lpc177x_8x_gpdma.h"
#include "debug_frmwrk.h"
#include "lpc177x_8x_rtc.h"
#include "lpc177x_8x_clkpwr.h"
#include "lpc177x_8x_timer.h"
#include "bsp.h"
#include "diskio.h"
#include "ff.h"
#include "sdram_k4s561632j.h"	
#include "GUI_Private.h"
#include "BUTTON.h"
#include "GUIDEMO.h"

#include "GUI.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "MainTask.h"
#include "function.h"
#include "lpc177x_8x_wwdt.h"
#include "app.h"
#include "platform_decode.h"

extern volatile platform_timer_counter uart0_timer;
extern volatile platform_timer_counter uart1_timer;
extern volatile platform_timer_counter uart2_timer;
extern volatile platform_timer_counter uart3_timer;

extern volatile platform_uart_buffer * uart0_recv_buffer;
extern volatile platform_uart_buffer * uart1_recv_buffer;
extern volatile platform_uart_buffer * uart2_recv_buffer;
extern volatile platform_uart_buffer * uart3_recv_buffer;

extern volatile platform_timer_counter adc_time_to_convert;
extern volatile unsigned char current_channel;
extern volatile unsigned char adc_wait_to_convert;

extern volatile unsigned char g_begin_gcode_calcu;

extern volatile long g_granularity;
 

extern volatile platform_cpld_value g_cpld_value;

extern volatile unsigned char g_cpld_done;
extern volatile unsigned char g_cpld_en;
 

volatile unsigned char g_begin_cpld_send=0;

extern volatile hyacinth_service *p_cpld_service;
 
extern volatile platform_gcode_buffer g_pgb[MAX_PGB_BUFFER_LENGTH];

extern volatile unsigned short g_x_speed;//x Freq Num
extern volatile unsigned short g_y_speed;//y Freq Num
extern volatile unsigned short g_z_speed;//z Freq Num

extern void *hyacinth_create(void);
extern hyacinth_service *hyacinth_get_service_handle(void *handle,const char *devname);
extern int  hyacinth_task_create(void *handle,unsigned char type,unsigned char priority,unsigned char is_permanent,void (*call_back)());
extern int  hyacinth_task_signal_box_push(void *handle,int src_task_id,int dest_task_id,void *data);
extern void*  hyacinth_task_signal_box_pop(void *handle,int *src_task_id,int dest_task_id);
extern void TC_Init(void);
extern void platform_init_uart_device(void);
extern void app_uart_recv_data(int task_id);
extern void platform_uart_init(void);
extern void platform_timer_init(void);
extern void platform_gpio_init(void);

extern void Squirrel_CalcuLineNextPoint(long current_x,long current_y,long *next_x,long *next_y,long start_x,long start_y,long end_x,long end_y,long granularity);

extern unsigned char lib_decode_command(const char* string);
extern unsigned char lib_decode_gcode(const char* string);
extern void app_decode_command(int task_id);

extern void app_handle_key_even(int task_id);
extern void app_I2C_read_data(int task_id);
#ifdef WIN32_PLATFORM
extern void CALLBACK TimerProc(HWND hwnd, UINT message, UINT timerID, DWORD time);
#endif

volatile FATFS fs;
volatile FIL fsrc, fdst, fdst1;
volatile FRESULT res; 
volatile FILINFO bmpfile, textfile;
volatile uint32_t w, filelen, br, bw;
uint8_t char_wr_ptr[30054];//[1920000];
uint8_t textbuffer[4096];
uint8_t manger[58856];
uint8_t Program_Coordinate[58856];
uint8_t Program_XYZ[58856];
uint8_t Program_G[58856];				 
uint8_t Parameter_Edit[58856];
uint8_t Auto_Edit[58856];
uint8_t Zero_Edit[58856];
uint8_t Help_Home[58856];
uint8_t	KND_logo[58856];
uint8_t textbuffer[4096];
uint8_t staff_info[6000];
uint8_t staff_table[1000][6] = {0};;	
extern page_t page[PAGE_SIZE];
extern char bBuffer[28];

extern volatile platform_timer_counter touch_time_to_convert;
extern volatile unsigned char g_app_touch_time_to_convert;

extern void Redraw_Callback(int pageid);
extern void handleSingnal_Callback(int pageid);

extern BUTTON_Handle hButton[CTRL_SIZE];
extern EDIT_Handle hEdit[CTRL_SIZE];
char * const textpath= "0:systemconfig.txt";

volatile unsigned char g_first_run =1;	

RTCTime RTC_Settime;

extern volatile platform_cpld_value g_cpld_value;
extern volatile unsigned char g_cpld_done;
extern volatile unsigned char g_cpld_en;

extern volatile platform_uart_buffer app_uart0_send_buffer;
extern volatile platform_timer_counter modbus_freq_command_time_to_send;
extern volatile unsigned char g_start_read_freq;
extern volatile platform_timer_counter modbus_frame_time_to_sand;//20ms
extern volatile unsigned char g_start_modbus_frame_send;
extern volatile platform_timer_counter gcode_pause_timer;
extern volatile unsigned char g_begin_decode_command;
extern  char s_command[DECODE_MAX_COMMAND_STATEMENT][DECODE_MAX_STATEMENT_LENGTH];
GUI_ConstString Text_ListBox[];
//int command_index = 0, statement_index = 0; 
int staff_num = 0;
//st_Wdt_Config wdtCfg;

/************************************************************************
	FUNCTION NAME : platform_init
	INPUTS: 
		none
	OUTPUTS:	
		none
	DESCRIPTION:	
		Platform init
************************************************************************/
void platform_init(void)
{
	platform_uart_init();
	platform_timer_init();
	platform_gpio_init();
	platform_pwm_init();
	platform_adc_init();
}



/************************************************************************
	FUNCTION NAME : main
	INPUTS: 
		int agrc,char* argv[]
	OUTPUTS:	
		none
	DESCRIPTION:	
		Main Function
************************************************************************/
int main(int agrc,char* argv[])
{
	#ifdef WIN32_PLATFORM
		MSG msg;
	#endif

	int ret = 0;
	int pageid = 1;
	const char *p0, *p1, *p2, *p3, *p4, *p5, *p6, *p7, *p8, *p9;
	volatile uint32_t w,filelen;
	volatile int flag = 1;
	RTC_TIME_Type *pFullTime;
	int textfile_length = 0, label=0;


	volatile unsigned char tick_cn=0;
	volatile unsigned int i=0;
	volatile void *handle = NULL;
	p0 = "0:bmp/coordinate.bmp";
	p1 = "0:bmp/pro_manager.bmp";
	p2 = "0:bmp/G_pro.bmp";
	p3 = "0:bmp/parama.bmp";
	p4 = "0:bmp/adminster.bmp";
	p5 = "0:bmp/auto.bmp";
	p6 = "0:bmp/zero.bmp";
	p7 = "0:bmp/help.bmp";
	p8 = "0:bmp/knd_logo.bmp";
	p9 = "0:/table/staff_table.txt";
	//textpath = "0:systemconfig.txt";
	
	disk_initialize(0);

	Bsp_init();

	GUI_Init();

	RTC_Init(LPC_RTC);

//	RTC_Settime.RTC_Year = 2011;
//	RTC_Settime.RTC_Mon = 11;
//	RTC_Settime.RTC_Mday = 29;
//	RTC_Settime.RTC_Hour = 18;
//	RTC_Settime.RTC_Min = 37;
//	RTC_Settime.RTC_Sec = 0;
//	RTC_Settime.RTC_Wday = 1;
//	RTC_Settime.RTC_Yday = 333;
//	RTCSetTime(RTC_Settime);
	RTCStart();
	
	WWDT_Init(0x3fffff);

	WWDT_SetMode(WWDT_RESET_MODE,ENABLE);

	WWDT_Enable(ENABLE);


	f_mount(0, &fs); 
	res=f_open(&fsrc, p0, FA_OPEN_EXISTING|FA_READ);
	if(res) 
	return FALSE;
	res=f_stat(p0, &bmpfile);
	if(res) return FALSE;
	filelen = bmpfile.fsize;
	f_read(&fsrc,Program_Coordinate,filelen,&w);

	res=f_open(&fsrc, p1, FA_OPEN_EXISTING|FA_READ);
	if(res) 
	return FALSE;
	res=f_stat(p1, &bmpfile);
	if(res) return FALSE;
	filelen = bmpfile.fsize;
	f_read(&fsrc,Program_XYZ,filelen,&w);

	res=f_open(&fsrc, p2, FA_OPEN_EXISTING|FA_READ);
	if(res) 
	return FALSE;
	res=f_stat(p2, &bmpfile);
	if(res) return FALSE;
	filelen = bmpfile.fsize;
	f_read(&fsrc,Program_G,filelen,&w);

	res=f_open(&fsrc, p3, FA_OPEN_EXISTING|FA_READ);
	if(res) 
	return FALSE;
	res=f_stat(p3, &bmpfile);
	if(res) return FALSE;
	filelen = bmpfile.fsize;
	f_read(&fsrc,Parameter_Edit,filelen,&w);

	res=f_open(&fsrc, p4, FA_OPEN_EXISTING|FA_READ);
	if(res) 
	return FALSE;
	res=f_stat(p4, &bmpfile);
	if(res) return FALSE;
	filelen = bmpfile.fsize;
	f_read(&fsrc,manger,filelen,&w);

	res=f_open(&fsrc, p5, FA_OPEN_EXISTING|FA_READ);
	if(res) 
	return FALSE;
	res=f_stat(p5, &bmpfile);
	if(res) return FALSE;
	filelen = bmpfile.fsize;
	f_read(&fsrc,Auto_Edit,filelen,&w);

	res=f_open(&fsrc, p6, FA_OPEN_EXISTING|FA_READ);
	if(res) 
	return FALSE;
	res=f_stat(p6, &bmpfile);
	if(res) return FALSE;
	filelen = bmpfile.fsize;
	f_read(&fsrc,Zero_Edit,filelen,&w);

	res=f_open(&fsrc, p7, FA_OPEN_EXISTING|FA_READ);
	if(res) 
	return FALSE;
	res=f_stat(p7, &bmpfile);
	if(res) return FALSE;
	filelen = bmpfile.fsize;
	f_read(&fsrc,Help_Home,filelen,&w);

	res=f_open(&fsrc, p8, FA_OPEN_EXISTING|FA_READ);
	if(res) 
	return FALSE;
	res=f_stat(p8, &bmpfile);
	if(res) return FALSE;
	filelen = bmpfile.fsize;
	f_read(&fsrc,KND_logo,filelen,&w);

	res=f_open(&fdst, p9, FA_OPEN_ALWAYS|FA_READ| FA_WRITE);
	if(res) 
	return FALSE;
	f_stat(p9, &textfile);
	textfile_length = textfile.fsize;
	for(;;)
	{
		if(textfile_length >= 511)
		{
			f_read(&fdst, &staff_info[label], 511, &br);
			textfile_length -= 511;
			label += 511;
			for (i = 1000; i > 0; i--);
		}
		else
		{
			f_read(&fdst, &staff_info[label], textfile.fsize - label, &br);
			break;
		}
	}

	f_close(&fsrc);	
	f_close(&fdst);
	f_mount(0, NULL);

	for(i = 0; i < sizeof(staff_info); i++)
	{
		static int staff_info_add = 0;
		if(staff_info[i] == '\n' )
		{
			staff_table[staff_num][staff_info_add]= '\0';
			staff_num++;
			staff_info_add = 0;
			
		}
		else if(staff_info[i] == '\r')
		{
			staff_table[staff_num][staff_info_add]= '\0';
			staff_info_add++;	
		}
		else if(staff_info[i] == '\0')
		{
			staff_table[staff_num][staff_info_add]= '\0';
			break;
		} 
		else 
		{
			staff_table[staff_num][staff_info_add]= staff_info[i];	
			staff_info_add++;
		}
	}

	GPIO_SetDir(1,1<<12,GPIO_DIRECTION_OUTPUT);
	
	GPIO_SetDir(1,1<<13,GPIO_DIRECTION_OUTPUT);

	for(tick_cn=0;tick_cn<10;tick_cn++)
	{
		for(i=0;i<2000000;i++);

		if(tick_cn%2==0)
		{
			GPIO_OutputValue(1,1<<13,1);
		}else
		{
			GPIO_OutputValue(1,1<<13,0);
		}
	}

	platform_init();

	platform_init_uart_device();//Install uart device
	
	platform_init_gpio_device();//Install gpio device

	platform_init_adc_device();//Install adc device

	platform_init_pwm_device();//Install pwm device

	platform_init_cpld_device();//Install cpld device
	
//	platform_init_decode_device();//Install decode device

	platform_init_gcode_device();//Install gcode device

	platform_init_cpld_device();//Install cpld device

//	platform_init_dac_device();//Install dac device
	
 	handle = hyacinth_create();

//	app_init();

	app_uart_init(handle);

	app_gpio_init(handle);

	app_adc_init(handle);

//	app_I2C_init(handle);

	app_touch_init(handle);

//	app_decode_init(handle);

	app_gcode_init(handle);

	app_cpld_init(handle);

//	app_dac_init(handle);

	app_pwm_init(handle);

	touch_init();

	TC_Init();//init timer0

	GUI_Delay(1000);

	_ExecCalibration();

	g_first_run =0;
	
	InitPageInformation(page);
	
	#ifdef WIN32_PLATFORM
		SetTimer(NULL, 0, 500, TimerProc);
	#endif
	


	hyacinth_task_create(handle, TASK_TYPE_CALLBACK, TASK_PRIORITY_NORMAL, TRUE, app_uart_recv_data);
	//hyacinth_task_create(handle, TASK_TYPE_CALLBACK, TASK_PRIORITY_NORMAL, TRUE, app_handle_key_even);
	hyacinth_task_create(handle, TASK_TYPE_CALLBACK, TASK_PRIORITY_NORMAL, TRUE, app_decode_command);
	

	#ifdef WIN32_PLATFORM
		SetTimer(NULL, 0, 500, TimerProc);
	#endif



	while(1)
	{ 

		//WWDT_FeedStdSeq();

		hyacinth_task_run(handle);

		if(flag)
		{
			ret = Redraw(pageid, Redraw_Callback);			
		}
		
		ret = handleSingnal(pageid, handleSingnal_Callback);
		if(ret == pageid)
		{
		 	flag = 0;
		}
		if(ret != pageid)
		{
			destroypage(pageid);
			pageid = ret;
			flag = 1;
		}
		
		#ifdef WIN32_PLATFORM
			if(GetMessage(&msg, NULL, 0, 0))
			{
				  TranslateMessage(&msg);
	 			  DispatchMessage(&msg);
			}
		#endif
		
	}
	
	return 0;
}

#ifdef WIN32_PLATFORM
void CALLBACK TimerProc(HWND hwnd, UINT message, UINT timerID, DWORD time)
{

 	platform_printf("Checking For Uart  Interface... \n");
	platform_printf("Checking For PWM Interface... \n");
	platform_printf("Checking For USB Interface... \n");
	platform_printf("Checking For CAN Interface... \n");
	platform_printf("Checking For NETWORK Interface... \n");
}
#endif


void TIMER0_IRQHandler(void)
{
	volatile static unsigned char tickcn=0;

	if(TIM_GetIntStatus(LPC_TIM0, TIM_MR0_INT) !=SET) return;

	platform_uart_send_data(PORT_UART0);

	platform_uart_recv_data(PORT_UART0);

	platform_uart_timer_counter(&uart0_timer,uart0_recv_buffer);


	switch(tickcn)
	{																					    
		case 0:
			if(adc_time_to_convert.start)
			{
				if(++adc_time_to_convert.counter >= adc_time_to_convert.counter_timeout)
				{
					adc_time_to_convert.counter = 0;
					
					adc_time_to_convert.start =0;
					
					app_adc_begin_to_convation(current_channel);
					
					adc_wait_to_convert =1;
							
				}
			}
			break;
		case 1:
			if(adc_wait_to_convert)
			{
				app_adc_time_to_get_value(current_channel);
			}
			break;
		case 2:
			if(touch_time_to_convert.start)
			{
				if(++touch_time_to_convert.counter >= touch_time_to_convert.counter_timeout)
				{
					touch_time_to_convert.counter =0;

					if(g_first_run)
					{
						GUI_TOUCH_Exec();
					}
					else
					{
						g_app_touch_time_to_convert =1;

					}
					
				}
			}

			platform_get_key_value();
			
			break;
		case 3:
			if(g_begin_cpld_send && p_cpld_service)
			{
				volatile platform_cpld_value pc_value;
				static int i=0;

				pc_value.Adr =CPLD_STR_REG;
				
				p_cpld_service->device_interface.ioctl(p_cpld_service->hanle,platform_cpld_app_call_device_op_cpld_read_word);
				p_cpld_service->device_interface.read(p_cpld_service->hanle,&pc_value,sizeof(platform_cpld_value));

				if(!(pc_value.Data & 0x8000)  && i<MAX_PGB_BUFFER_LENGTH)//15bit 
				{
					pc_value.Data =0;//clear

					if(g_pgb[i].buse)
					{
						if(g_pgb[i].point.x>0)
						{
							pc_value.Adr = CPLD_X_CTR;
							pc_value.Data = (1<<15)|((g_pgb[i].dir &GCODE_X_DIRECTION?1:0)<<14)|(g_x_speed &0x3FF);

							p_cpld_service->device_interface.ioctl(p_cpld_service->hanle,platform_cpld_app_call_device_op_cpld_write_word);
							p_cpld_service->device_interface.write(p_cpld_service->hanle,&pc_value,sizeof(platform_cpld_value));

							pc_value.Adr = CPLD_X_NUM;
							pc_value.Data =g_pgb[i].point.x; 

							p_cpld_service->device_interface.write(p_cpld_service->hanle,&pc_value,sizeof(platform_cpld_value));

							
						}
						if(g_pgb[i].point.y>0)
						{
							pc_value.Adr = CPLD_Y_CTR;
							pc_value.Data = (1<<15)|((g_pgb[i].dir &GCODE_Y_DIRECTION?1:0)<<14)|(g_y_speed &0x3FF);

							p_cpld_service->device_interface.ioctl(p_cpld_service->hanle,platform_cpld_app_call_device_op_cpld_write_word);
							p_cpld_service->device_interface.write(p_cpld_service->hanle,&pc_value,sizeof(platform_cpld_value));

							pc_value.Adr = CPLD_Y_NUM;
							pc_value.Data =g_pgb[i].point.y; 

							p_cpld_service->device_interface.write(p_cpld_service->hanle,&pc_value,sizeof(platform_cpld_value));
						}

						if(g_pgb[i].point.z>0)
						{
							pc_value.Adr = CPLD_Z_CTR;
							pc_value.Data = (1<<15)|((g_pgb[i].dir &GCODE_Z_DIRECTION?1:0)<<14)|(g_z_speed &0x3FF);

							p_cpld_service->device_interface.ioctl(p_cpld_service->hanle,platform_cpld_app_call_device_op_cpld_write_word);
							p_cpld_service->device_interface.write(p_cpld_service->hanle,&pc_value,sizeof(platform_cpld_value));

							pc_value.Adr = CPLD_Z_NUM;
							pc_value.Data =g_pgb[i].point.z; 

							p_cpld_service->device_interface.write(p_cpld_service->hanle,&pc_value,sizeof(platform_cpld_value));
						}

						pc_value.Adr = CPLD_WRITE_FINISH_REG;
						pc_value.Data =0x5555;//whatever data

						p_cpld_service->device_interface.ioctl(p_cpld_service->hanle,platform_cpld_app_call_device_op_cpld_write_word);
						p_cpld_service->device_interface.write(p_cpld_service->hanle,&pc_value,sizeof(platform_cpld_value));
						
						i++;

						
					}else
					{
						i=0;
						g_begin_cpld_send=0;
						g_begin_decode_command =1;
					}
					
				}
			}

			break;
		case 4:

			break;
		case 5:
			if(gcode_pause_timer.start)
			{
				if(++gcode_pause_timer.counter>=gcode_pause_timer.counter_timeout)
				{
					gcode_pause_timer.start =0;
					gcode_pause_timer.counter =0;
					g_begin_decode_command =1;
				}
			}
			break;
		case 6:
			break;
		case 7:
			app_gpio_get_value();
			break;
		default:
			break;
	}

	if(++tickcn>=8) tickcn=0;

	TIM_ClearIntPending(LPC_TIM0,TIM_MR0_INT);

}

























